#include "stdafx.h"
#include "Common.h"


void WinHttp_CallBack(AsyncWinHttp* asyncWinHttp)
{
	if (asyncWinHttp->status.Status() == ASYNC_WINHTTP_ERROR)
	{
		printf("%S", asyncWinHttp->status.Desc().c_str());
	}
	else
	{
		//std::string response;
		//asyncWinHttp->GetResponseRaw(response);
		//printf("%s", response.c_str());
	}
	SetEvent(asyncWinHttp->hEvent_);
}

int DictRectify(LPSTR src, LPWSTR sMp3URL, LPWSTR sMeaning, BOOL bChineseToEnglish)
{
    char *p1, *p2, *tmpbuf;
    int len, len2, ret;
    BOOL bMP3Valid = TRUE;

    p2 = src;
    p1 = strstr(src, "<audio>");
    if (p1)
    {
        p1 += 7;
    }
    else
    {
        bMP3Valid = FALSE;
    }

    if (TRUE == bMP3Valid)
    {
        p2 = strstr(p1, "</audio>");
        if (p2)
        {
        }
        else
        {
            bMP3Valid = FALSE;
        }
    }

    if (TRUE == bMP3Valid)
    {
        len = p2 - p1;
        ret = MultiByteToWideChar(CP_ACP,0,p1,len,sMp3URL, MP3URL_LEN);
        if (ret == 0)
        {
            *sMp3URL = _T('\0');
        }
        *(sMp3URL+len) = 0;
    }
    else
    {
        *sMp3URL = _T('\0');
    }

    p1 = strstr(p2+8, "<def>");
    if (NULL == p1)
    {
        return 4;
    }
    len = p1 - src;
    len2 = strlen(src) - len;
    tmpbuf = new char[len2];
    p1 += 4;
    int inside = 0;
    p2 = tmpbuf;
    while (*p1++)
    {
        if (1 == inside)
        {
            // inside xml value
            if (('>' == *p1) || (';' == *p1))
            {
                inside = 0;
            }
        } 
        else
        {
            // normal text
            if ( ('<' == *p1) || ('&' == *p1))
            {
                inside = 1;
            } 
            else if ('\n' == *p1)
            {
                *p2++ = '\r';
                *p2++ = *p1;
            } 
            else
            {
                *p2++ = *p1;
            }
        }
    }
    *p2 = 0;
    len2 = strlen(tmpbuf);
    if (TRUE == bChineseToEnglish)
    {
        ret = MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,tmpbuf, len2,sMeaning, 2*len2);
    } 
    else
    {
        ret = MultiByteToWideChar(CP_UTF8,0,tmpbuf, len2,sMeaning, 2*len2);
    }
    if (ret == 0)
    {
        delete [] tmpbuf;
        return 5;
    }

    delete [] tmpbuf;

    return 0;
}

int CnkiRectify(LPSTR src, LPWSTR sMeaning)
{
    char *p1, *p2, *tmpbuf;
    int len2, ret;

    p1 = strstr(src, "<font class=\"text6\">");
    if (NULL == p1)
    {
        return 1;
    }
    p2 = strstr(p1, "<td align=\"left\" class=\"text4\">");
    if (NULL == p2)
    {
        return 2;
    }

    len2 = (int)(p2 - p1);
    *p2 = 0;
    tmpbuf = new char[len2];
    int inside = 0;
    p2 = tmpbuf;
    p1--;
    while (*p1++)
    {
        if (1 == inside)
        {
            // inside xml value
            if (('>' == *p1) || (';' == *p1))
            {
                inside = 0;
            }
        } 
        else
        {
            // normal text
            if ( ('<' == *p1) || ('&' == *p1))
            {
                inside = 1;
            } 
            else if (')' == *p1)
            {
                *p2++ = ')';
                *p2++ = '\r';
                *p2++ = '\n';
            } 
            else
            {
                *p2++ = *p1;
            }
        }
    }
    *p2 = 0;
    len2 = strlen(tmpbuf);
    ret = MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,tmpbuf, len2,sMeaning, 2*len2);
    if (ret == 0)
    {
        delete [] tmpbuf;
        return 5;
    }

    delete [] tmpbuf;

    return 0;
}

void UnicodeToGB2312URL(wchar_t * pData,CString* strOut)
{
    int len = wcslen(pData);
    char *buf;
    buf = (char *)malloc(2*len + 10);
    WideCharToMultiByte(CP_ACP,NULL,pData,-1,buf,2*len+10,NULL,NULL);
    CString strOneChar;
    for (int i=0; i<2*len; i++)
    {
        strOneChar.Format(_T("%%%02X"),(unsigned char)(*(buf+i)));
        strOut->Append(strOneChar);
    }
    free(buf);
    return;
}

void UnicodeToURL(wchar_t * pData,CString* strOut)
{
    int len = wcslen(pData);
    CString strOneChar;
    for (int i=0; i<len; i++)
    {
        strOneChar.Format(_T("%04X"),(*(pData+i)));
        strOut->Append(_T("%u"));
        strOut->Append(strOneChar);
    }
    return;
}

int bcisalpha(WCHAR ch)
{
    if ((ch >=_T('A')) && (ch <=_T('Z')))
    {
        return 1;
    }
    if ((ch >=_T('a')) && (ch <=_T('z')))
    {
        return 1;
    }
    return 0;
}

#ifdef _DEBUG
VOID dbgPrintf(LPTSTR fmt, ...)
{
    va_list marker;
    WCHAR szBuf[1024];

    va_start(marker, fmt);
    wvsprintf(szBuf, fmt, marker);
    va_end(marker);

    OutputDebugString(szBuf);
    OutputDebugString(TEXT("\r\n"));
}
#endif


unsigned long GetIndex(WCHAR * buf)
{
#define TMP_BUF_LEN 10
    WCHAR tmp[TMP_BUF_LEN], c0, c1, c2;
    unsigned long ret;

    wcsncpy(tmp, buf, 3);
    tmp[3] = 0;
    _wcslwr(tmp);
    c0 = tmp[0];
    c1 = tmp[1];
    c2 = tmp[2];

    if ((c0 >_T('z')) || (c0 <_T('a')))
    {
        return 0;
    }
    
    if ((c1 >_T('z')) || (c1 <_T('a')))
    {
        c1 = c2 =_T('a');
    }

    if ((c2 >_T('z')) || (c2 <_T('a')))
    {
        c2 =_T('a');
    }


    ret = (c0-_T('a'));
    ret *= ENG_LETTER_NUM;
    ret += (c1-_T('a'));
    ret *= ENG_LETTER_NUM;
    ret += (c2-_T('a'))+1;

    return (ret);
}

// return 0 if found, other value for error.
int WordQuery( unsigned long lBeginPos, unsigned long lEndPos,WCHAR *from, WCHAR *to, unsigned long *indexBuf, FILE *fp)
{
    unsigned long posCurrent;
    WCHAR sCurrentLine[LINE_BUF_LEN], chSign,  *pTabpos;
    int len, iDstWordLen;


    len = wcslen(from);
    if (len > 3)
    {
        chSign = *(from+3);
    } 
    else if (len == 3)
    {
        chSign =_T('a');
    }
    else
    {
        chSign =_T('z');
    }
    fseek(fp, lBeginPos, SEEK_SET);
    for (;;)
    {
        fgetws(sCurrentLine, LINE_BUF_LEN, fp);
        posCurrent = ftell(fp);
        if (posCurrent > lEndPos)
        {
            return 3;
        }
        if (feof(fp))
        {
            return 4;
        }
        pTabpos = wcschr(sCurrentLine,_T('\t'));
        if (NULL == pTabpos)
        {
            continue;
        }
        else
        {
            iDstWordLen = pTabpos - sCurrentLine;
            if (iDstWordLen > 3)
            {
                if (0 == memcmp(sCurrentLine, from, 3*sizeof(WCHAR)))
                {
                    if (bcisalpha(sCurrentLine[3]))
                    {
                        if (sCurrentLine[3]>chSign)
                        {
                            return 6;
                        }
                    }
                }
                else
                {
                    continue;
                }
            }
        }
        if (iDstWordLen == len)
        {
            if (0 == memcmp(sCurrentLine, from, len*sizeof(WCHAR)))
            {
                wcscpy(to, sCurrentLine);
                return 0;
            }
        }
    }

    return 5;
}

int WordQueryRect(WCHAR *from, WCHAR *rectify, WCHAR *to, unsigned long *indexBuf, FILE *fp)
{
    unsigned long lPos1, lPos2, lIndex, posCurrent;
    unsigned long *lptmp;
    WCHAR sCurrentLine[LINE_BUF_LEN];

    lIndex = GetIndex(from);
    lptmp = indexBuf + lIndex;
    lPos1 = *(lptmp);
    if (0 == lPos1)
    {
        return 1;
    }

    for (++lptmp;0==(*lptmp);lptmp++);
    lPos2 = *lptmp;
    if (lPos2 < lPos1)
    {
        // error
        return 2;
    }
    if ((lPos2 - lPos1) > MAX_GAP_DICT)
    {
        lPos2 = MAX_GAP_DICT + lPos1;
    }

    CString strFrom = from;
    int pos, len;
    BOOL bPhrase;
    pos = strFrom.Find(_T('\n'));
    if (pos > 0)
    {
        strFrom.Replace(_T("\r\n"),_T(" "));
        strFrom.Replace(_T("\n"),_T(" "));
    }
    pos = strFrom.Find(_T(' '));
    if (pos > 0)
    {
        len = pos;
        bPhrase = TRUE;
    }
    else
    {
        len = strFrom.GetLength();
        bPhrase = FALSE;
    }

    if (len > 7)
    {
        len -=4;
        fseek(fp, lPos1, SEEK_SET);
        for (;;)
        {
            posCurrent = ftell(fp);
            fgetws(sCurrentLine, LINE_BUF_LEN, fp);
            if (posCurrent > lPos2)
            {
                return 3;
            }
            if (feof(fp))
            {
                return 4;
            }
            if (0 == _wcsnicmp(from, sCurrentLine, len))
            {
                break;
            }
        }
        lPos1 = posCurrent;
    }

    int ret;
    ret = WordQuery(lPos1, lPos2, from, to, indexBuf, fp);

    if (ret)
    {
        CString strLwr = strFrom;
        strLwr.MakeLower();
        if (strLwr != strFrom)
        {
            strFrom=strLwr;
            ret = WordQuery(lPos1, lPos2, strFrom.GetBuffer(), to, indexBuf, fp);
        }
    }

    if (0 == ret)
    {
        wcscpy(rectify, strFrom.GetBuffer());
        return ret;
    }

    if (TRUE == bPhrase)
    {
        strFrom += _T(" ");
        strFrom.Replace(_T("  "),_T(" "));
    }
    else
    {
        strFrom += _T(" ");
    }


    pos = strFrom.Find(_T("ied "));
    if (pos > 0)
    {
        strFrom.Replace(_T("ied "),_T("y "));
    }
    else if (strFrom.Find(_T("ies "))>0)
    {
        strFrom.Replace(_T("ies "),_T("y "));
    }
    else if ((pos = strFrom.Find(_T("ing ")))>0)
    {
        CString strTmp = strFrom;
        strTmp.Replace(_T("ing "),_T(" "));
        strTmp.TrimRight();
        ret = WordQuery(lPos1, lPos2, strTmp.GetBuffer(), to, indexBuf, fp);
        if (ret)
        {
            // not find
            strTmp = strFrom;
            strTmp.Replace(_T("ing "),_T("e "));
            strTmp.TrimRight();
            ret = WordQuery(lPos1, lPos2, strTmp.GetBuffer(), to, indexBuf, fp);
            if (ret)
            {
                if (strFrom.GetAt(pos-1) == strFrom.GetAt(pos-2))
                {
                    CString subString = strFrom.Mid(pos -1, 5);
                    strFrom.Replace(subString, _T(" "));
                } 
                else
                {
                    strFrom.Replace(_T("ing "),_T(" "));
                }
            }
            else
            {
                wcscpy(rectify, strTmp.GetBuffer());
                return 0;
            }
        }
        else
        {
            wcscpy(rectify, strTmp.GetBuffer());
            return 0;
        }
    }
    else if ((pos = strFrom.Find(_T("ed ")))>0)
    {
        // similar with ing
        CString strTmp = strFrom;
        strTmp.Replace(_T("ed "),_T(" "));
        strTmp.TrimRight();
        ret = WordQuery(lPos1, lPos2, strTmp.GetBuffer(), to, indexBuf, fp);
        if (ret)
        {
            strTmp = strFrom;
            strTmp.Replace(_T("ed "),_T("e "));
            strTmp.TrimRight();
            ret = WordQuery(lPos1, lPos2, strTmp.GetBuffer(), to, indexBuf, fp);
            if (ret)
            {
                // not find
                if (strFrom.GetAt(pos-1) == strFrom.GetAt(pos-2))
                {
                    CString subString = strFrom.Mid(pos -1, 4);
                    strFrom.Replace(subString, _T(" "));
                } 
                else
                {
                    strFrom.Replace(_T("ed "),_T(" "));
                }
            }
            else
            {
                wcscpy(rectify, strTmp.GetBuffer());
                return 0;
            }
        }
        else
        {
            wcscpy(rectify, strTmp.GetBuffer());
            return 0;
        }
    }
    else if (strFrom.Find(_T("es "))>0)
    {
        CString strTmp = strFrom;
        strTmp.Replace(_T("es "),_T(" "));
        strTmp.TrimRight();
        ret = WordQuery(lPos1, lPos2, strTmp.GetBuffer(), to, indexBuf, fp);
        if (ret)
        {
            strFrom.Replace(_T("es "),_T("e "));
        }
        else
        {
            wcscpy(rectify, strTmp.GetBuffer());
            return 0;
        }
    }
    else if (strFrom.Find(_T("s "))>0)
    {
        strFrom.Replace(_T("s "),_T(" "));
    }

    strFrom.TrimRight();
    ret = WordQuery(lPos1, lPos2, strFrom.GetBuffer(), to, indexBuf, fp);
    if (0 == ret)
    {
        wcscpy(rectify, strFrom.GetBuffer());
    }
    return ret;
}

BOOL HasChinese(WCHAR *src)
{
    WCHAR ch;
    
    int len = wcslen(src);
    if (len > 5)
    {
        len = 5;
    }
    for (int i=0; i < len; i++)
    {
        ch = *(src+i);
        if ((ch >=MIN_CN_UNICODE) && (ch <= MAX_CN_UNICODE))
        {
            return TRUE;
        }
    }
    return FALSE;
}

int PlayMp3(WCHAR *filename)
{
    WCHAR   buf[128];   

    //use   mciSendCommand   
    MCI_OPEN_PARMS   mciOpen;   
    MCIERROR   mciError;   
    mciOpen.lpstrDeviceType   =   _T("mpegvideo");
    mciOpen.lpstrElementName   =   filename;   
    mciError   =   mciSendCommand(0,MCI_OPEN,MCI_OPEN_TYPE   |   MCI_OPEN_ELEMENT,(DWORD)&mciOpen);   
    if(mciError)   
    {   
        mciGetErrorString(mciError,buf,128);   
        // MessageBox("send MCI_PLAY command failed", "ERROR");    
        return 3;   
    }   
    UINT   DeviceID   =   mciOpen.wDeviceID   ;   
    MCI_PLAY_PARMS   mciPlay;   

    mciError   =   mciSendCommand(DeviceID, MCI_PLAY, MCI_WAIT,
        (DWORD)   (LPMCI_PLAY_PARMS)&mciPlay);  //MCI_DGV_PLAY_REPEAT, Ҫ #include "Digitalv.h"
    if(mciError)   
    { 
        mciGetErrorString(mciError,buf,128);     
        //MessageBox("send MCI_PLAY command failed", "ERROR");   
        return 4;   
    }   
    return 0;
}

// return 0, if is a valid word to be translate, return non zero, if no need to be translated
int StringTrim(WCHAR *from, WCHAR *to)
{
    int len, len2, lPos1, lPos2,i;
    WCHAR *pPos;

    pPos = from;
    len = wcslen(from);
    for (i=0;i<len;i++, pPos++)
    {
        if (bcisalpha((*pPos)))
        {
            break;
        }
    }
    if (i==len)
    {
        return 1;  // illegal word ???
    } 
    else
    {
        lPos1 = i;
    }

    i = len - 1;
    pPos = from + i;
    for (;i>=0;i--,pPos--)
    {
        if (bcisalpha((*pPos)))
        {
            break;
        }
    }
    lPos2 = i;
    if (lPos2 <= lPos1)
    {
        return 2;  // ??? impossible???
    } 

    len2 = lPos2 - lPos1+1;
    wcsncpy(to, from+lPos1, len2);
    *(to+len2)=0;

    if (len2 == len)
    {
        return -1;  // exactly pure word, no prefix and postfix spaces.
    }
    return 0;
}

// TRUE if file exist, FALSE not exist
BOOL IsFileExist(CString csFilePath)
{
    CFileFind find; 
    BOOL bExist;
    if(find.FindFile(csFilePath)) 
    {
        bExist = TRUE;
    }
    else
    {
        bExist = FALSE;
    }
    find.Close();
    return bExist;
}

// get file length
ULONG GetFileLength(CString csFilePath)
{
    CFileFind find; 
    ULONG len;
    
    if(find.FindFile(csFilePath)) 
    {
        find.FindNextFile();
        len = (ULONG)find.GetLength();
    }
    else
    {
        len = 0;
    }
    find.Close();
    return len;
}

#define ABS(x,y) ((x)>(y)?(x)-(y):(y)-(x))
// compare 2 strings, return the count of same char from begin
float StringCmp(WCHAR *from, int len, WCHAR *to)
{
    int iCase, i, tmp;
    WCHAR *p1, *p2;
    const int iGap = 32;  // 'a' - 'A'

    for (iCase=0, i = 0, p1 = from, p2=to; i<len; i++)
    {
        tmp = ABS(*p1, *p2);
        if (0 != tmp)
        {
            if (tmp == iGap)
            {
                iCase++;
            }
            else
            {
                break;
            }
        }
        else
        {
            // equal , do nothing
        }

        if (0 == *p2)
        {
            break;
        }
    }
    return (float)(i+0.1*iCase/len);
}

#if 0
FILE * fp;
fp = _wfopen(_T("d:\\test.txt"),_T("rb"));
if (NULL != fp)
{
    fgetws(sCurrentLine, LINE_BUF_LEN, fp);
    GetDlgItem(IDC_ST_PHONETIC)->SetWindowText(sCurrentLine);
    fclose(fp);
}
else
{
    GetDlgItem(IDC_ST_PHONETIC)->SetWindowText(_T("Test Asdf"));
}

m_pFont->CreateFont(18, // nHeight
                    0, // nWidth
                    0, // nEscapement
                    0, // nOrientation
                    FW_THIN, // nWeight
                    FALSE, // bItalic
                    FALSE, // bUnderline
                    0, // cStrikeOut
                    ANSI_CHARSET, // nCharSet
                    OUT_DEFAULT_PRECIS, // nOutPrecision
                    CLIP_DEFAULT_PRECIS, // nClipPrecision
                    PROOF_QUALITY, // nQuality
                    DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
                    _T("Lingoes Unicode")); // lpszFac

GetDlgItem(IDC_ST_PHONETIC)->SetFont(m_pFont); 
#endif